home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
fax
/
src
/
util
/
faxcron.sh
< prev
next >
Wrap
Linux/UNIX/POSIX Shell Script
|
1994-08-01
|
10KB
|
372 lines
#! /bin/sh
# $Header: /usr/people/sam/fax/util/RCS/faxcron.sh,v 1.8 1994/04/18 21:35:05 sam Rel $
#
# FlexFAX Facsimile Software
#
# Copyright (c) 1993, 1994 Sam Leffler
# Copyright (c) 1993, 1994 Silicon Graphics, Inc.
#
# Permission to use, copy, modify, distribute, and sell this software and
# its documentation for any purpose is hereby granted without fee, provided
# that (i) the above copyright notices and this permission notice appear in
# all copies of the software and related documentation, and (ii) the names of
# Sam Leffler and Silicon Graphics may not be used in any advertising or
# publicity relating to the software without the specific, prior written
# permission of Sam Leffler and Silicon Graphics.
#
# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
#
# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
#
#
# Script to run periodically from cron:
#
# 1. Purge info directory of old remote machine capabilities.
# 2. Truncate log files to delete old information.
# 3. Purge old files in the received facsimile queue.
# 4. Notify about sites that are currently having jobs rejected.
#
SPOOL=/usr/spool/fax
JUNK=/tmp/faxcron$$
XFERLOG=$SPOOL/etc/xferlog
LAST=$SPOOL/etc/lastrun
AGEINFO=30 # purge remote info after 30 days inactivity
AGELOG=30 # keep log info for last 30 days
FAXUSER=fax # owner of log files
LOGMODE=0644 # mode for log files
PATH=/bin:/usr/bin:/etc
test -d /usr/ucb && PATH=$PATH:/usr/ucb # Sun and others
test -d /usr/bsd && PATH=$PATH:/usr/bsd # Silicon Graphics
test -d /usr/5bin && PATH=/usr/5bin:$PATH:/usr/etc # Sun and others
test -d /usr/sbin && PATH=/usr/sbin:$PATH # 4.4BSD-derived
AWK=nawk
# look for an an awk: nawk, gawk, awk
($AWK '{}' </dev/null >/dev/null) 2>/dev/null ||
{ AWK=gawk; ($AWK '{}' </dev/null >/dev/null) 2>/dev/null || AWK=awk; }
RM="rm -f"
TEE=tee
CP=cp
MV=mv
CHOWN=chown
CHMOD=chmod
UPDATE="date +'%D %R' >$LAST"
while [ x"$1" != x"" ] ; do
case $1 in
-n) RM=true; TEE=true; CP=true; MV=true;
CHOWN=true; CHMOD=true
UPDATE=true
;;
-*) echo "Usage: $0 [-n]"; exit 1;;
esac
shift
done
trap "rm -f \$JUNK; exit 1" 0 1 2 15
cd $SPOOL
echo "Report failed calls and associated session logs:"
LASTRUN=`cat $LAST 2>/dev/null`
$AWK '
#
# Sort array a[l..r]
#
function qsort(a, l, r) {
i = l;
k = r+1;
item = a[l];
for (;;) {
while (i < r) {
i++;
if (a[i] >= item)
break;
}
while (k > l) {
k--;
if (a[k] <= item)
break;
}
if (i >= k)
break;
t = a[i]; a[i] = a[k]; a[k] = t;
}
t = a[l]; a[l] = a[k]; a[k] = t;
if (k != 0 && l < k-1)
qsort(a, l, k-1);
if (k+1 < r)
qsort(a, k+1, r);
}
func cleanup(s)
{
gsub("\"", "", s);
gsub("^ +", "", s);
gsub(" +$", "", s);
return s;
}
func isBefore(d)
{
split(d, a, " ");
split(a[1], b, "/");
return (b[3] < LASTd[3] \
|| b[2] < LASTd[2] \
|| b[1] < LASTd[1] \
|| a[2] <= LASTdt[2]);
}
func setupToLower()
{
upperRE = "[ABCDEFGHIJKLMNOPQRSTUVWXYZ]";
upper["A"] = "a"; upper["B"] = "b"; upper["C"] = "c";
upper["D"] = "d"; upper["E"] = "e"; upper["F"] = "f";
upper["G"] = "g"; upper["H"] = "h"; upper["I"] = "i";
upper["J"] = "j"; upper["K"] = "k"; upper["L"] = "l";
upper["M"] = "m"; upper["N"] = "n"; upper["O"] = "o";
upper["P"] = "p"; upper["Q"] = "q"; upper["R"] = "r";
upper["S"] = "s"; upper["T"] = "t"; upper["U"] = "u";
upper["V"] = "v"; upper["W"] = "w"; upper["X"] = "x";
upper["Y"] = "y"; upper["Z"] = "z";
}
func toLower(s)
{
if (match(s, upperRE) != 0) {
do {
c = substr(s, RSTART, 1);
gsub(c, upper[c], s);
} while (match(s, upperRE));
}
return s;
}
#
# Accumulate a statistics record.
#
func acct(dest, status, datetime)
{
if (isBefore(datetime))
return;
status = cleanup(status);
if (length(status) > 11) {
msg = toLower(substr(status, 1, 11));
if (callFailed[msg])
return;
if (skipError[msg])
return;
}
if (status != "") {
dest = cleanup(dest);
datetime = cleanup(datetime);
for (i = 0; i < nerrmsg; i++)
if (errmsg[i] == status)
break;
if (i == nerrmsg)
errmsg[nerrmsg++] = status;
if (errinfo[dest] == "")
errinfo[dest] = datetime "@" i;
else
errinfo[dest] = errinfo[dest] "|" datetime "@" i;
}
}
func printTranscript(canon, datetime)
{
gsub("[^0-9]", "", canon);
split(datetime, parts, " ");
split(parts[1], p, "/");
cmd = sprintf(TRANSCRIPT, canon, months[p[1]], p[2], parts[2]);
system(cmd);
}
BEGIN { FS="\t";
callFailed["busy signal"] = 1;
callFailed["unknown pro"] = 1;
callFailed["no carrier "] = 1;
callFailed["no local di"] = 1;
callFailed["no answer f"] = 1;
skipError["job aborted"] = 1;
skipError["invalid dia"] = 1;
skipError["can not loc"] = 1;
months["01"] = "Jan"; months["02"] = "Feb";
months["03"] = "Mar"; months["04"] = "Apr";
months["05"] = "May"; months["06"] = "Jun";
months["07"] = "Jul"; months["08"] = "Aug";
months["09"] = "Sep"; months["10"] = "Oct";
months["11"] = "Nov"; months["12"] = "Dec";
split(LASTRUN, LASTdt, " ");
split(LASTdt[1], LASTd, "/");
setupToLower();
}
$2 == "SEND" && NF == 9 { acct($4, $9, $1); }
$2 == "SEND" && NF == 11 { acct($5, $11, $1); }
END { nsorted = 0;
for (key in errinfo)
sorted[nsorted++] = key;
qsort(sorted, 0, nsorted-1);
for (k = 0; k < nsorted; k++) {
key = sorted[k];
n = split(errinfo[key], a, "|");
for (i = 1; i <= n; i++) {
m = split(a[i], b, "@");
if (m != 2)
continue;
printf "\n"
printf "To: %-16.16s Date: %s\n", key, b[1]
printf "Error: %s\n\n", errmsg[b[2]]
printTranscript(key, b[1]);
}
}
}
' LASTRUN="$LASTRUN" TRANSCRIPT="\
LOGFILE=$SPOOL/log/%s;\
TMP=/tmp/faxlog\$\$;\
if [ -f \$LOGFILE ]; then\
sed -n -e '/%s %s %s.*SESSION BEGIN/,/SESSION END/p' \$LOGFILE |\
sed -e '/start.*timer/d'\
-e '/stop.*timer/d'\
-e '/-- data/d'\
-e 's/^/ /' >\$TMP;\
fi;\
if [ -s \$TMP ]; then\
cat \$TMP;\
else\
echo ' No transcript available.';\
fi;\
rm -f \$TMP\
" $XFERLOG
$RM $LAST; eval $UPDATE
echo ""
#
# Collect phone numbers that haven't been called
# in the last $AGE days. We use this to clean up
# the info and log files.
#
find info -ctime +$AGEINFO -print >$JUNK
echo "Purge cache of fax machine capabilities:"
for i in `cat $JUNK`; do
echo " $i"
$RM $i
done
echo ""
echo "Truncate old session logs:"
TODAY="`date +'%h %d %T'`"
for i in log/*; do
START=`$AWK -F: '
#
# Setup data conversion data structures.
#
func setupDateTimeStuff()
{
Months["Jan"] = 0; Months["Feb"] = 1; Months["Mar"] = 2;
Months["Apr"] = 3; Months["May"] = 4; Months["Jun"] = 5;
Months["Jul"] = 6; Months["Aug"] = 7; Months["Sep"] = 8;
Months["Oct"] = 9; Months["Nov"] = 10; Months["Dec"] = 11;
daysInMonth[ 0] = 31; daysInMonth[ 1] = 28; daysInMonth[ 2] = 31;
daysInMonth[ 3] = 30; daysInMonth[ 4] = 31; daysInMonth[ 5] = 30;
daysInMonth[ 6] = 31; daysInMonth[ 7] = 31; daysInMonth[ 8] = 30;
daysInMonth[ 9] = 31; daysInMonth[10] = 30; daysInMonth[11] = 31;
FULLDAY = 24 * 60 * 60;
}
#
# Convert MMM DD hh:mm:ss.ms to seconds.
# NB: this does not deal with leap years.
#
func cvtTime(s)
{
mon = Months[substr(s, 0, 3)];
yday = substr(s, 5, 2) - 1;
for (i = 0; i < mon; i++)
yday += daysInMonth[i];
s = substr(s, 7);
t = i = 0;
for (n = split(s, a, ":"); i++ < n; )
t = t*60 + a[i];
return yday*FULLDAY + t;
}
BEGIN { setupDateTimeStuff();
KEEP = cvtTime(TODAY) - AGE*FULLDAY;
lastRecord = "$"
}
{ if (cvtTime($1 ":" $2 ":" $3) >= KEEP) {
lastRecord = NR; exit
}
}
END { print lastRecord }
' TODAY="$TODAY" AGE=$AGELOG $i` 2>/dev/null
if [ "$START" != 1 ]; then
sed 1,${START}d $i >$JUNK
if [ -s $JUNK ]; then
$MV $JUNK $i; $CHOWN ${FAXUSER} $i; $CHMOD ${LOGMODE} $i
ls -ls $i
else
echo " Remove empty $i"
$RM $i
fi
fi
done
echo ""
#
# Purge old stuff from the receive queue.
#
find recvq -mtime +7 -print >$JUNK
echo "Purge old stuff in receive queue:"
if [ -s $JUNK ]; then
(for i in `cat $JUNK`; do
bin/faxinfo $i
$RM $i >/dev/null 2>&1
done) | $AWK -F: '
/recvq.*/ { file=$1; }
/Sender/ { sender = $2; }
/Pages/ { pages = $2; }
/Quality/ { quality = $2; }
/Received/ { date = $2;
for (i = 3; i <= NF; i++)
date = date ":" $i;
printf " %-16.16s %21.21s %2d %8s%s\n", \
file, sender, pages, quality, date;
}
'
fi
echo ""
#
# Note destinations whose jobs are currently being rejected.
#
grep "^rejectNotice:" info/* cinfo/* 2>/dev/null | $AWK -F: '
{ reason = $3;
for (i = 4; i <= NF; i++)
reason = reason ":" $i;
sub("^[ ]*", "", reason);
if (reason != "") {
sub(".*/", "", $1);
printf "Rejecting jobs to +%s because \"%s\".\n", \
$1, reason;
}
}
'